#ifndef __C_ARCH_CPU_H__
#define __C_ARCH_CPU_H__

#include "std/std.h"

#ifdef __cplusplus
extern "C" {
#endif

#define NR_IRQS			(16)

#ifdef TEST_DBG_WIN32

#define __nop()				do {} while (0)
#define __cli() 			do {} while (0)
#define __sti()				do {} while (0)
#define __halt()			do {} while (0)
#define __safe_halt()		do {} while (0)

#define __flush_tlb()		do {} while (0)
#define __load_cr3(pgd)		do {} while (0)

// interrupt control
#define __save_flags(x)		do {} while (0)
#define __restore_flags(x)  do {} while (0)

// for spinlocks
#define local_irq_save(x)	do {} while (0)

#else

#define __nop()				__asm__ __volatile__ ("nop")
#define __cli() 			__asm__ __volatile__("cli": : :"memory")
#define __sti()				__asm__ __volatile__("sti": : :"memory")
#define __halt()			__asm__ __volatile__("hlt": : :"memory")
#define __safe_halt()		__asm__ __volatile__("sti; hlt": : :"memory")

#define __flush_tlb()						\
	do {									\
	unsigned int tmpreg;					\
	\
	__asm__ __volatile__(					\
	"movl %%cr3, %0;  # flush TLB \n"		\
	"movl %0, %%cr3;              \n"		\
	: "=r" (tmpreg)							\
	:: "memory");							\
	} while (0)

#define __load_cr3(pgd)						\
	do {									\
	__asm__ __volatile__ (					\
		"mov %0,%%cr3"::"a"((uint)(pgd))	\
		);									\
	} while (0)

// interrupt control
#define __save_flags(x)		__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
#define __restore_flags(x)  __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")

// for spinlocks
#define local_irq_save(x)		__asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")

#endif

#define local_irq_restore(x)	__restore_flags(x)
#define local_irq_disable()		__cli()
#define local_irq_enable()		__sti()

typedef struct kernel_stat
{
	uint irqs[NR_CPUS][NR_IRQS];
	uint content_switch;
}
kernel_stat_t;

extern kernel_stat_t kstat;

#ifdef VIEWS_SMP_ENABLED
#else

#define cli()					__cli()
#define sti()					__sti()
#define save_flags(x)			__save_flags(x)
#define restore_flags(x)		__restore_flags(x)

#define smp_processor_id()		(0)

#endif

#ifdef __cplusplus
}
#endif
#endif
/* EOF */
